package com.sinping.qh.service.admin.lab.impl;

import com.mongodb.*;
import com.sinping.qh.api.exception.HandlerException;
import com.sinping.qh.api.support.*;
import com.sinping.qh.domain.lab.LabInspectItemRelationDomain;
import com.sinping.qh.domain.lab.LabInspectItemTreeDomain;
import com.sinping.qh.domain.lab.LaboratoryDomain;
import com.sinping.qh.dto.admin.lab.InspectItemHiddenDangerDto;
import com.sinping.qh.dto.admin.lab.LabInspectItemRelationDto;
import com.sinping.qh.dto.admin.lab.LabInspectItemTreeDto;
import com.sinping.qh.dto.admin.lab.LabOrderDto;
import com.sinping.qh.dto.auth.UserSessionDTO;
import com.sinping.qh.query.lab.LabInspectItemTreeConditionQuery;
import com.sinping.qh.query.lab.LabInspectItemTreeQuery;
import com.sinping.qh.repository.mongo.lab.LabInspectItemRelationRepository;
import com.sinping.qh.repository.mongo.lab.LabInspectItemTreeRepository;
import com.sinping.qh.repository.mongo.lab.LaboratoryRepository;
import com.sinping.qh.service.MongoManager;
import com.sinping.qh.service.admin.lab.ILabInspectItemTreeService;
import com.sinping.qh.service.auth.ISessionService;
import com.sinping.qh.service.common.CommonDbConst;
import com.sinping.qh.utils.mapper.BeanMapper;
import com.sinping.qh.utils.mapper.JsonMapper;
import com.sinping.qh.utils.misc.IdGenerator;
import org.apache.commons.lang3.StringUtils;

import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @author jiahuaiqing
 * @create 2018/6/9
 */
@Service
public class LabInspectItemServiceTreeImpl implements ILabInspectItemTreeService {

    @Autowired
    LabInspectItemTreeRepository labInspectItemTreeRepository;

    @Autowired
    LaboratoryRepository laboratoryRepository;

    @Autowired
    LabInspectItemRelationRepository labInspectItemRelationRepository;

    @Autowired
    MongoManager mongoManager;

    @Qualifier("sessionServiceRedisImpl")
    @Autowired
    ISessionService iSessionService;

    @Autowired
    MongoTemplate mongoTemplate;

    @Override
    public ResDto addLabInspectItemOne(HttpServletRequest request, LabInspectItemTreeDto labInspectItemTreeDto) {
        String token = request.getHeader(Const.TOKEN_NAME);
        UserSessionDTO userSessionDTO = iSessionService.getSessionByToken(token);
        if (userSessionDTO == null) {
            return new ResDto(Const.PARAM_ERROR, "用户未登录");
        }
        //验证参数
        if (StringUtils.isBlank(userSessionDTO.getId())) {
            return new ResDto(Const.SERVER_ERROR, "获取用户id失败");
        }

        String itemCategory = labInspectItemTreeDto.getItemCategory();
        String itemName = labInspectItemTreeDto.getItemName();
        String itemSubcategory = labInspectItemTreeDto.getItemSubcategory();
        List<LabInspectItemTreeDomain> domain = labInspectItemTreeRepository.findByItemNameAndItemCategoryAndItemSubcategoryAndStatus(itemName, itemCategory, itemSubcategory, "0");
        if (domain != null && domain.size() > 0) {
            return new ResDto(Const.SERVER_ERROR, "检查项已经存在");
        }
        LabInspectItemTreeDomain dtoTODomain = BeanMapper.map(labInspectItemTreeDto, LabInspectItemTreeDomain.class);
        dtoTODomain.setId(IdGenerator.uuid2());
        dtoTODomain.setItemName(itemName);
        dtoTODomain.setItemCategory(itemCategory);
        dtoTODomain.setItemSubcategory(itemSubcategory);
        dtoTODomain.setItemLevel("1");
        dtoTODomain.setItemParentId("0");
        dtoTODomain.setStatus("0");
        dtoTODomain.setChildCount(0);
        dtoTODomain.setCreateUserId(userSessionDTO.getId());
        dtoTODomain.setItemOrder(new ObjectId());
        dtoTODomain.setGmtCreated(new Date());
        dtoTODomain.setGmtModified(new Date());
        LabInspectItemTreeDomain save = labInspectItemTreeRepository.save(dtoTODomain);
        if (save == null) {
            return new ResDto(Const.SERVER_ERROR, "一级检查项添加失败");
        }
        LabInspectItemTreeDto saveDto = BeanMapper.map(save, LabInspectItemTreeDto.class);
        ResDto resDto = new ResDto(Const.SUCCESS, "一级检查项添加成功");
        resDto.setDatas(JsonMapper.defaultMapper().toJson(saveDto));
        return resDto;
    }

    @Override
    public ResDto addLabInspectItemTwo(HttpServletRequest request, LabInspectItemTreeDto labInspectItemTreeDto) {
        String token = request.getHeader(Const.TOKEN_NAME);
        UserSessionDTO userSessionDTO = iSessionService.getSessionByToken(token);
        if (userSessionDTO == null) {
            return new ResDto(Const.PARAM_ERROR, "用户未登录");
        }
        //验证参数
        if (StringUtils.isBlank(userSessionDTO.getId())) {
            return new ResDto(Const.SERVER_ERROR, "获取用户id失败");
        }

        String itemCategory = labInspectItemTreeDto.getItemCategory();
        String itemName = labInspectItemTreeDto.getItemName();
        String itemParentId = labInspectItemTreeDto.getItemParentId();
        //LabInspectItemDomain domain = labInspectItemRepository.findByItemNameAndItemParentIdAndItemCategory(itemName, itemParentId, itemCategory);
        List<LabInspectItemTreeDomain> domainList = labInspectItemTreeRepository.findByItemNameAndItemParentIdAndItemLevelAndStatus(itemName, itemParentId, "2", "0");
        if (domainList != null && domainList.size() > 0) {
            return new ResDto(Const.SERVER_ERROR, "二级检查项已经存在");
        }
        LabInspectItemTreeDomain parentDomain = labInspectItemTreeRepository.findOne(itemParentId);
        if (parentDomain == null) {
            return new ResDto(Const.SERVER_ERROR, "父id不存在");
        }
        if (!"1".equals(parentDomain.getItemLevel())) {
            return new ResDto(Const.SERVER_ERROR, "父id必须是一级检查项");
        }
        LabInspectItemTreeDomain dtoTODomain = BeanMapper.map(labInspectItemTreeDto, LabInspectItemTreeDomain.class);
        dtoTODomain.setId(IdGenerator.uuid2());
        dtoTODomain.setItemName(itemName);
        //用的是父级的类型和分类
        dtoTODomain.setItemSubcategory(parentDomain.getItemSubcategory());
        //这个用的是传来的传，且只能为1 隐患
        dtoTODomain.setItemCategory(itemCategory);
        dtoTODomain.setItemLevel("2");
        dtoTODomain.setStatus("0");
        dtoTODomain.setChildCount(0);
        dtoTODomain.setItemParentId(itemParentId);
        dtoTODomain.setCreateUserId(userSessionDTO.getId());
        dtoTODomain.setItemOrder(new ObjectId());
        dtoTODomain.setGmtCreated(new Date());
        dtoTODomain.setGmtModified(new Date());
        LabInspectItemTreeDomain save = labInspectItemTreeRepository.save(dtoTODomain);
        if (save == null) {
            return new ResDto(Const.SERVER_ERROR, "二级检查项添加失败");
        }
        //增加一级childCount数
        int childCountOne = parentDomain.getChildCount();
        parentDomain.setChildCount(childCountOne + 1);
        LabInspectItemTreeDomain saveChildCount = labInspectItemTreeRepository.save(parentDomain);
        if (saveChildCount == null) {
            return new ResDto(Const.SERVER_ERROR, "增加一级的子类数量失败");
        }
        LabInspectItemTreeDto saveDto = BeanMapper.map(save, LabInspectItemTreeDto.class);
        ResDto resDto = new ResDto(Const.SUCCESS, "二级检查项添加成功");
        resDto.setDatas(JsonMapper.defaultMapper().toJson(saveDto));
        return resDto;
    }

    @Override
    public ResDto addLabInspectItemThree(HttpServletRequest request, LabInspectItemTreeDto labInspectItemTreeDto) {
        String token = request.getHeader(Const.TOKEN_NAME);
        UserSessionDTO userSessionDTO = iSessionService.getSessionByToken(token);
        if (userSessionDTO == null) {
            return new ResDto(Const.PARAM_ERROR, "用户未登录");
        }
        //验证参数
        if (StringUtils.isBlank(userSessionDTO.getId())) {
            return new ResDto(Const.SERVER_ERROR, "获取用户id失败");
        }

        String itemName = labInspectItemTreeDto.getItemName();
        String itemParentId = labInspectItemTreeDto.getItemParentId();
        List<LabInspectItemTreeDomain> domainList = labInspectItemTreeRepository.findByItemNameAndItemParentIdAndItemLevelAndStatus(itemName, itemParentId, "3", "0");
        if (domainList != null && domainList.size() > 0) {
            return new ResDto(Const.SERVER_ERROR, "隐患描述已经存在");
        }
        LabInspectItemTreeDomain parentDomain = labInspectItemTreeRepository.findOne(itemParentId);
        if (parentDomain == null) {
            return new ResDto(Const.SERVER_ERROR, "父id不存在");
        }
        if (!"2".equals(parentDomain.getItemLevel())) {
            return new ResDto(Const.SERVER_ERROR, "父id必须是二级检查项");
        }
        LabInspectItemTreeDomain dtoTODomain = BeanMapper.map(labInspectItemTreeDto, LabInspectItemTreeDomain.class);
        dtoTODomain.setId(IdGenerator.uuid2());
        dtoTODomain.setItemName(itemName);
        dtoTODomain.setItemLevel("3");
        //用的是父级的类型和分类
        dtoTODomain.setItemCategory(parentDomain.getItemCategory());
        dtoTODomain.setItemSubcategory(parentDomain.getItemSubcategory());
        dtoTODomain.setStatus("0");
        dtoTODomain.setChildCount(0);
        dtoTODomain.setItemParentId(itemParentId);
        dtoTODomain.setCreateUserId(userSessionDTO.getId());
        dtoTODomain.setItemOrder(new ObjectId());
        dtoTODomain.setGmtCreated(new Date());
        dtoTODomain.setGmtModified(new Date());
        LabInspectItemTreeDomain save = labInspectItemTreeRepository.save(dtoTODomain);
        if (save == null) {
            return new ResDto(Const.SERVER_ERROR, "隐患描述添加失败");
        }
        //增加二级childCount数
        int childCountTwo = parentDomain.getChildCount();
        parentDomain.setChildCount(childCountTwo + 1);
        LabInspectItemTreeDomain saveChildCount = labInspectItemTreeRepository.save(parentDomain);
        if (saveChildCount == null) {
            return new ResDto(Const.SERVER_ERROR, "增加二级的子类数量失败");
        }
        LabInspectItemTreeDto saveDto = BeanMapper.map(save, LabInspectItemTreeDto.class);
        ResDto resDto = new ResDto(Const.SUCCESS, "隐患描述添加成功");
        resDto.setDatas(JsonMapper.defaultMapper().toJson(saveDto));
        return resDto;
    }

    /**
     * 实验室配置检查项（后台和app共用此方法）
     *
     * @param request
     * @param relationDto
     * @return
     */
    @Override
    public ResDto addLaboratoryInspectItemRelation(HttpServletRequest request, LabInspectItemRelationDto relationDto) {
//        String token = request.getHeader(Const.TOKEN_NAME);
//        UserSessionDTO userSessionDTO = iSessionService.getSessionByToken(token);
//        if (userSessionDTO == null) {
//            return new ResDto(Const.PARAM_ERROR, "用户未登录");
//        }
//        //验证参数
//        if (StringUtils.isBlank(userSessionDTO.getId())) {
//            return new ResDto(Const.SERVER_ERROR, "获取用户id失败");
//        }
        try {
            LaboratoryDomain lab = laboratoryRepository.findOne(relationDto.getLabId());
            if (lab == null) {
                return new ResDto(Const.SERVER_ERROR, "实验室id不存在");
            }
            //配置之前先根据labid先清库(现在不用)
//            List<LabInspectItemRelationDomain> byLabId = labInspectItemRelationRepository.findByLabId(relationDto.getLabId());
//            if (byLabId != null && byLabId.size() > 0) {
//                for (LabInspectItemRelationDomain domain : byLabId) {
//                    labInspectItemRelationRepository.delete(domain);
//                }
//            }
            List<String> inspectItemIds = relationDto.getInspectItemIds();
            if (inspectItemIds.size() > 0) {
                for (String inspectItemId : inspectItemIds) {
                    LabInspectItemRelationDomain LabRelationDomain = labInspectItemRelationRepository.findByLabIdAndInspectItemId(lab.getId(), inspectItemId);
                    if (LabRelationDomain == null) {//没有配置检查项，就添加到关系表中
                        LabInspectItemRelationDomain relationDomain = new LabInspectItemRelationDomain();
                        relationDomain.setId(IdGenerator.uuid2());
                        relationDomain.setGmtCreated(new Date());
                        relationDomain.setGmtModified(new Date());
                        relationDomain.setLabId(relationDto.getLabId());
                        relationDomain.setInspectItemId(inspectItemId);
                        labInspectItemRelationRepository.save(relationDomain);
                    }
                }
                return new ResDto(Const.SUCCESS, "实验室配置检查项成功");
            } else {
                return new ResDto(Const.SERVER_ERROR, "实验室配置检查项失败！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ResDto(Const.SERVER_ERROR, "实验室配置检查项异常！");
        }

    }

    @Override
    public ResDto deleteLaboratoryInspectItemRelation(HttpServletRequest request, LabInspectItemRelationDto labInspectItemTreeDto) {
        try {
            LaboratoryDomain lab = laboratoryRepository.findOne(labInspectItemTreeDto.getLabId());
            if (lab == null) {
                return new ResDto(Const.SERVER_ERROR, "实验室id不存在");
            }
            //删除已经配置的检查项
            List<String> inspectItemIds = labInspectItemTreeDto.getInspectItemIds();
            for (String inspectimteid : inspectItemIds) {
                LabInspectItemRelationDomain labinspectDomain = labInspectItemRelationRepository.findByLabIdAndInspectItemId(labInspectItemTreeDto.getLabId(), inspectimteid);
                labInspectItemRelationRepository.delete(labinspectDomain);
            }
            return new ResDto(Const.SUCCESS, "实验室检查项删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            return new ResDto(Const.SERVER_ERROR, "实验室配置检查项异常！");
        }
    }

    /**
     * 获取--实验室已经配置的检查项
     *
     * @param request
     * @param labId
     * @return
     */
    @Override
    public ResDto getLaboratoryInspectItemRelation(HttpServletRequest request, String labId) {
        String token = request.getHeader(Const.TOKEN_NAME);
        UserSessionDTO userSessionDTO = iSessionService.getSessionByToken(token);
        if (userSessionDTO == null) {
            return new ResDto(Const.PARAM_ERROR, "用户未登录");
        }
        //验证参数
        if (StringUtils.isBlank(userSessionDTO.getId())) {
            return new ResDto(Const.SERVER_ERROR, "获取用户id失败");
        }
        List<LabInspectItemRelationDomain> byLabId = labInspectItemRelationRepository.findByLabId(labId);
        if (byLabId == null || byLabId.size() == 0) {
            return new ResDto(Const.SUCCESS, "");
        }
        List<LabInspectItemRelationDto> labInspectItemRelationDtos = BeanMapper.mapList(byLabId, LabInspectItemRelationDto.class);
        String labInspectItemDtosStr = JsonMapper.defaultMapper().toJson(labInspectItemRelationDtos);
        ResDto resDto = new ResDto(ConstEum.SUCCESS);
        resDto.setDatas(labInspectItemDtosStr);
        return resDto;
    }

    /**
     * 用在隐患记录中添加隐患描述(包含[院系隐患或实验室隐患]+危险源隐患)
     *
     * @param request
     * @param itemSubcategory
     * @param lab_id
     * @return
     */
    @Override
    public ResDto getLabInspectItemDescRelation(HttpServletRequest request, String itemSubcategory, String lab_id) {
//app和admin同一个方法，故注释下面的用户验证登录代码
//        String token = request.getHeader(Const.TOKEN_NAME);
//        UserSessionDTO userSessionDTO = iSessionService.getSessionByToken(token);
//        if (userSessionDTO == null) {
//            return new ResDto(Const.PARAM_ERROR, "用户未登录");
//        }
//        //验证参数
//        if (StringUtils.isBlank(userSessionDTO.getId())) {
//            return new ResDto(Const.SERVER_ERROR, "获取用户id失败");
//        }
        try {

            List<InspectItemHiddenDangerDto> weixianyuanList = null;
            if (StringUtils.isNotBlank(lab_id)) {
                weixianyuanList = getWeixianYuanList(lab_id);
            }


            List<InspectItemHiddenDangerDto> yuanxiAndLabList = getLabDangerByitemSubcategory(itemSubcategory);
            if (null != weixianyuanList && weixianyuanList.size() > 0) {
                yuanxiAndLabList.addAll(weixianyuanList);
            }
            String labInspectItemDtosStr = JsonMapper.defaultMapper().toJson(yuanxiAndLabList);
            ResDto resDto = new ResDto(ConstEum.SUCCESS);
            resDto.setDatas(labInspectItemDtosStr);
            return resDto;
        } catch (Exception e) {
            e.printStackTrace();
            return new ResDto(Const.SERVER_ERROR, "获取实验室检查项的隐患记录异常！");
        }

    }

    @Override
    public ResDto putLabInspectItemDescOrder(HttpServletRequest request, LabOrderDto labOrderDto) {
        String token = request.getHeader(Const.TOKEN_NAME);
        UserSessionDTO userSessionDTO = iSessionService.getSessionByToken(token);
        if (userSessionDTO == null) {
            return new ResDto(Const.PARAM_ERROR, "用户未登录");
        }
        //验证参数
        if (StringUtils.isBlank(userSessionDTO.getId())) {
            return new ResDto(Const.SERVER_ERROR, "获取用户id失败");
        }
        try {
            ObjectId before = labOrderDto.getBefore();
            ObjectId after = labOrderDto.getAfter();
            LabInspectItemTreeDomain beforeDomain = labInspectItemTreeRepository.findByItemOrder(before);
            if (beforeDomain == null) {
                return new ResDto(Const.SERVER_ERROR, "before不存在");
            }
            LabInspectItemTreeDomain afterDomain = labInspectItemTreeRepository.findByItemOrder(after);
            if (afterDomain == null) {
                return new ResDto(Const.SERVER_ERROR, "after不存在");
            }
            beforeDomain.setItemOrder(after);
            labInspectItemTreeRepository.save(beforeDomain);
            afterDomain.setItemOrder(before);
            labInspectItemTreeRepository.save(afterDomain);
            ResDto resDto = new ResDto(Const.SUCCESS, "排序成功");
            return resDto;
        } catch (Exception e) {
            e.printStackTrace();
            return new ResDto(Const.SERVER_ERROR, "排序处理异常");
        }
    }

    /**
     * 根据lab_id来查出，已经配置危险源隐患
     *
     * @param lab_id
     * @return
     */
    private List<InspectItemHiddenDangerDto> getWeixianYuanList(String lab_id) {
        //实验室检查项关系表中查：byLabId注意是一级和二级检查项的id集合
        List<LabInspectItemRelationDomain> byLabId = labInspectItemRelationRepository.findByLabId(lab_id);
        List<InspectItemHiddenDangerDto> weixianyuanList = null;
        if (byLabId != null && byLabId.size() > 0) {
            weixianyuanList = getLabDangerByitemSubcategory(byLabId);
        }
        return weixianyuanList;
    }

    /**
     * 根据分类来查出--院系级和实验室级的检查项
     *
     * @param item_subcategory
     * @return
     */
    private List<InspectItemHiddenDangerDto> getLabDangerByitemSubcategory(String item_subcategory) {
        LabInspectItemTreeQuery labInspectItemTreeQuery = new LabInspectItemTreeQuery();
        //先查询全部危险源隐患列表,再取一级，再取二级...(好处是只查询一次库)
        labInspectItemTreeQuery.setItemSubcategory(item_subcategory);
        labInspectItemTreeQuery.setStatus("0");

        List<LabInspectItemTreeDomain> labInspectItemDomains = mongoManager.find(labInspectItemTreeQuery, LabInspectItemTreeDomain.class);
        List<InspectItemHiddenDangerDto> treeByInspectItem = null;
        if (null != labInspectItemDomains && labInspectItemDomains.size() > 0) {
            treeByInspectItem = this.createTreeByInspectItemAndSubcategory(labInspectItemDomains);
        }
        //List<LabInspectItemTreeDto> labInspectItemDtos = BeanMapper.mapList(labInspectItemDomains, LabInspectItemTreeDto.class);
        //String labInspectItemDtosStr = JsonMapper.defaultMapper().toJson(treeByInspectItem);
        return treeByInspectItem;
    }

    /**
     * 根据已经配置的检查项id--查出已经配置检查项的所有信息
     *
     * @param byLabId 一定注意了 byLabId是一级的id集合,byLabIdOther 二级的id
     * @return
     */
    private List<InspectItemHiddenDangerDto> getLabDangerByitemSubcategory(List<LabInspectItemRelationDomain> byLabId) {
        LabInspectItemTreeQuery labInspectItemTreeQuery = new LabInspectItemTreeQuery();
        //先查询全部危险源隐患列表,再取一级，再取二级...(好处是只查询一次库)
        labInspectItemTreeQuery.setItemSubcategory("2");
        labInspectItemTreeQuery.setStatus("0");

        List<LabInspectItemTreeDomain> labInspectItemDomains = mongoManager.find(labInspectItemTreeQuery, LabInspectItemTreeDomain.class, new Sort(Sort.Direction.DESC, "item_order"));
        List<InspectItemHiddenDangerDto> treeByInspectItem = null;
        if (null != labInspectItemDomains && labInspectItemDomains.size() > 0) {
            treeByInspectItem = this.createTreeByInspectItemAndSubcategory(labInspectItemDomains, byLabId);
        }
        return treeByInspectItem;
    }

    public List<InspectItemHiddenDangerDto> createTreeByInspectItemAndSubcategory(List<LabInspectItemTreeDomain> domainList, List<LabInspectItemRelationDomain> byLabId) {
        //一级检查项id集合
        List<String> byLabIdOne = new ArrayList<>();
        //不是一级的检查项id集合
        List<String> byLabIdOther = new ArrayList<>();
        for (LabInspectItemRelationDomain labInspectItemRelationDomain :byLabId) {
            String inspectItemIdTwo =labInspectItemRelationDomain.getInspectItemId();
            //查询检查项的id
            LabInspectItemTreeDomain two = labInspectItemTreeRepository.findOne(inspectItemIdTwo);
            if (two.getItemLevel().equals("1") &&
                    !(byLabIdOne.contains(two.getId()))) {
                byLabIdOne.add(two.getId());
            }
            if (!two.getItemLevel().equals("1") &&
                    !(byLabIdOne.contains(two.getId()))) {
                byLabIdOther.add(two.getId());
            }
        }

        List<InspectItemHiddenDangerDto> dtoList = new ArrayList<>();
        for (LabInspectItemTreeDomain domain : domainList) {
            //查出一级危险源隐患并且一级id是已经配置的
            if (domain.getItemLevel().equals("1") && byLabIdOne.contains(domain.getId())) {

                InspectItemHiddenDangerDto dto = new InspectItemHiddenDangerDto();
                dto.setId(domain.getId());
                dto.setChildCount(domain.getChildCount());
                dto.setItemName(domain.getItemName());
                dto.setItemCategory(domain.getItemCategory());
                dto.setItemSubcategory(domain.getItemSubcategory());
                dto.setStatus(domain.getStatus());
                dto.setItemParentId(domain.getItemParentId());
                dto.setItemLevel(domain.getItemLevel());
                dtoList.add(dto);

                createTreeBy(dto, domainList, byLabIdOther);
            }
        }
        return dtoList;
    }

    /**
     * 查出来的是一级二级和三级(只查ItemSubcategory为 0 和 1的数据)
     *
     * @param domainList
     * @return
     */
    public List<InspectItemHiddenDangerDto> createTreeByInspectItemAndSubcategory(List<LabInspectItemTreeDomain> domainList) {
        List<InspectItemHiddenDangerDto> dtoList = new ArrayList<>();
        for (LabInspectItemTreeDomain domain : domainList) {
            if (domain.getItemLevel().equals("1") && domain.getItemSubcategory().equals("0")) {
                InspectItemHiddenDangerDto dto = new InspectItemHiddenDangerDto();
                dto.setItemName(domain.getItemName());
                dto.setId(domain.getId());
                dto.setItemLevel(domain.getItemLevel());
                dto.setChildCount(domain.getChildCount());
                dto.setItemCategory(domain.getItemCategory());
                dto.setItemSubcategory(domain.getItemSubcategory());
                dto.setStatus(domain.getStatus());
                dto.setItemParentId(domain.getItemParentId());
                dto.setItemLevel(domain.getItemLevel());
                dtoList.add(dto);
                createTreeBy(dto, domainList);

            } else if (domain.getItemLevel().equals("1") && domain.getItemSubcategory().equals("1")) {
                InspectItemHiddenDangerDto dto = new InspectItemHiddenDangerDto();
                dto.setId(domain.getId());
                dto.setItemName(domain.getItemName());
                dto.setItemLevel(domain.getItemLevel());
                dto.setChildCount(domain.getChildCount());
                dto.setItemCategory(domain.getItemCategory());
                dto.setItemSubcategory(domain.getItemSubcategory());
                dto.setStatus(domain.getStatus());
                dto.setItemParentId(domain.getItemParentId());
                dto.setItemLevel(domain.getItemLevel());
                dtoList.add(dto);
                createTreeBy(dto, domainList);
            }
        }
        return dtoList;
    }

    /**
     * 已经配置的检查项（二级和三级） 注意：byLabIdOther 二级的id
     *
     * @param inspectItemHiddendto
     * @param domainList
     * @param byLabIdOther
     */
    private void createTreeBy(InspectItemHiddenDangerDto inspectItemHiddendto, List<LabInspectItemTreeDomain> domainList, List<String> byLabIdOther) {
        for (LabInspectItemTreeDomain domain : domainList) {
            //这里选择二级和三级
            if (domain.getItemLevel() != null && !domain.getItemLevel().equals("1") && inspectItemHiddendto.getId().equals(domain.getItemParentId())) {
                //检查项的id必须是在已经配置的集合中的
                if (byLabIdOther.contains(domain.getId())) {
                    List<InspectItemHiddenDangerDto> childrenList = inspectItemHiddendto.getChildDtoList();
                    if (childrenList == null) {
                        childrenList = new ArrayList<>();
                    }

                    InspectItemHiddenDangerDto dto2 = new InspectItemHiddenDangerDto();
                    dto2.setId(domain.getId());
                    dto2.setChildCount(domain.getChildCount());
                    dto2.setItemName(domain.getItemName());
                    dto2.setItemCategory(domain.getItemCategory());
                    dto2.setItemSubcategory(domain.getItemSubcategory());
                    dto2.setStatus(domain.getStatus());
                    dto2.setItemLevel(domain.getItemLevel());
                    dto2.setItemParentId(domain.getItemParentId());
                    dto2.setItemLevel(domain.getItemLevel());

                    childrenList.add(dto2);
                    inspectItemHiddendto.setChildDtoList(childrenList);

                    //递归
                    createTreeBy(dto2, domainList);

                }

            }
        }
    }

    /**
     * 所有检查项（二级和三级）
     *
     * @param inspectItemHiddendto
     * @param domainList
     */
    private void createTreeBy(InspectItemHiddenDangerDto inspectItemHiddendto, List<LabInspectItemTreeDomain> domainList) {
        for (LabInspectItemTreeDomain domain : domainList) {
            //这里选择二级和三级
            if (domain.getItemLevel() != null && !domain.getItemLevel().equals("1") && inspectItemHiddendto.getId().equals(domain.getItemParentId())) {
                List<InspectItemHiddenDangerDto> childrenList = inspectItemHiddendto.getChildDtoList();
                if (childrenList == null) {
                    childrenList = new ArrayList<>();
                }

                InspectItemHiddenDangerDto dto2 = new InspectItemHiddenDangerDto();
                dto2.setId(domain.getId());
                dto2.setItemName(domain.getItemName());
                dto2.setChildCount(domain.getChildCount());
                dto2.setItemCategory(domain.getItemCategory());
                dto2.setItemSubcategory(domain.getItemSubcategory());
                dto2.setStatus(domain.getStatus());
                dto2.setItemParentId(domain.getItemParentId());
                dto2.setItemOrder(domain.getItemOrder() == null ? null : domain.getItemOrder().toString());
                dto2.setItemLevel(domain.getItemLevel());

                childrenList.add(dto2);
                inspectItemHiddendto.setChildDtoList(childrenList);

                //递归
                createTreeBy(dto2, domainList);
            }
        }
    }

    @Override
    public ResDto updateLabInspectItem(HttpServletRequest request, LabInspectItemTreeDto labInspectItemTreeDto) {
        String token = request.getHeader(Const.TOKEN_NAME);
        UserSessionDTO userSessionDTO = iSessionService.getSessionByToken(token);
        if (userSessionDTO == null) {
            return new ResDto(Const.PARAM_ERROR, "用户未登录");
        }
        //验证参数
        if (StringUtils.isBlank(userSessionDTO.getId())) {
            return new ResDto(Const.SERVER_ERROR, "获取用户id失败");
        }

        LabInspectItemTreeDomain labInspectItemDomain = labInspectItemTreeRepository.findOne(labInspectItemTreeDto.getId());
        if (labInspectItemDomain == null) {
            return new ResDto(Const.SERVER_ERROR, "id不存在");
        }
        try {
            String itemLevel = labInspectItemDomain.getItemLevel();
            switch (itemLevel) {
                case "1":
                    if (!StringUtils.isNotBlank(labInspectItemTreeDto.getItemCategory())) {
                        return new ResDto(Const.PARAM_ERROR, "类型不为空");
                    }
                    if (!StringUtils.isNotBlank(labInspectItemTreeDto.getItemSubcategory())) {
                        return new ResDto(Const.PARAM_ERROR, "分类不为空");
                    }
                    String itemName = labInspectItemTreeDto.getItemName();
                    String itemCategory = labInspectItemTreeDto.getItemCategory();
                    String itemSubcategory = labInspectItemTreeDto.getItemSubcategory();
//                    LabInspectItemTreeDomain oneDomain = labInspectItemTreeRepository.findByItemNameAndItemCategoryAndItemSubcategory(itemName, itemCategory, itemSubcategory);
//                    if (oneDomain != null) {
//                        return new ResDto(Const.SERVER_ERROR, "此检查项已经存在");
//                    }
                    labInspectItemDomain.setItemName(labInspectItemTreeDto.getItemName());
                    labInspectItemDomain.setItemSubcategory(labInspectItemTreeDto.getItemSubcategory());
                    labInspectItemDomain.setItemCategory(labInspectItemTreeDto.getItemCategory());
                    labInspectItemDomain.setGmtModified(new Date());
                    //修改一级
                    labInspectItemTreeRepository.save(labInspectItemDomain);
                    break;
                case "2":
                default://3
                    String itemNameStr = labInspectItemDomain.getItemName();
                    String itemParentIdStr = labInspectItemDomain.getItemParentId();
//                    LabInspectItemTreeDomain twoThreeDomain = labInspectItemTreeRepository.findByItemNameAndItemParentId(itemNameStr, itemParentIdStr);
//                    if (twoThreeDomain != null) {
//                        return new ResDto(Const.SERVER_ERROR, "此检查项已经存在");
//                    }
                    labInspectItemDomain.setItemName(labInspectItemTreeDto.getItemName());
                    labInspectItemDomain.setItemCategory(labInspectItemTreeDto.getItemCategory());
                    labInspectItemDomain.setGmtModified(new Date());
                    labInspectItemTreeRepository.save(labInspectItemDomain);
                    break;
            }
            return new ResDto(Const.SUCCESS, "修改成功");
        } catch (Exception e) {
            e.printStackTrace();
            return new ResDto(Const.SERVER_ERROR, "修改失败");
        }
    }

    @Override
    public ResDto deleteLabInspectItemById(String id) {
        LabInspectItemTreeDomain labInspectItemDomain = labInspectItemTreeRepository.findOne(id);
        if (labInspectItemDomain == null) {
            return new ResDto(Const.SERVER_ERROR, "id不存在");
        }
        String itemLevel = labInspectItemDomain.getItemLevel();
        String status = labInspectItemDomain.getStatus();
        if (status.equals("1")) {
            return new ResDto(Const.SERVER_ERROR, "id已经删除啦");
        }
        try {
            if (itemLevel.equals("3")) {
                //labInspectItemTreeRepository.delete(id);
                labInspectItemDomain.setStatus("1");
                LabInspectItemTreeDomain save = labInspectItemTreeRepository.save(labInspectItemDomain);
                if (save == null) {
                    return new ResDto(Const.SERVER_ERROR, "删除隐患描述失败");
                }
                //修改childCount
                String itemParentId = labInspectItemDomain.getItemParentId();
                LabInspectItemTreeDomain two = labInspectItemTreeRepository.findOne(itemParentId);
                two.setChildCount(two.getChildCount() == 0 ? 0 : (two.getChildCount() - 1));
                LabInspectItemTreeDomain saveTwo = labInspectItemTreeRepository.save(two);
                if (saveTwo == null) {
                    return new ResDto(Const.SERVER_ERROR, "删除隐患描述时修改二级子类数量失败");
                }
            } else {//itemLevel为 1和2
                //查询此id下有几个子类
                List<LabInspectItemTreeDomain> countList = labInspectItemTreeRepository.findByItemParentIdAndStatus(id, "0");
                if (null == countList || countList.isEmpty()) {
                    //labInspectItemTreeRepository.delete(id);
                    labInspectItemDomain.setStatus("1");
                    LabInspectItemTreeDomain save = labInspectItemTreeRepository.save(labInspectItemDomain);
                    if (save == null) {
                        return new ResDto(Const.SERVER_ERROR, "删除失败");
                    }
                    //删除二级时修改一级子类数量(一级不需要修改)
                    if (itemLevel.equals("2")) {
                        String itemParentId = labInspectItemDomain.getItemParentId();
                        LabInspectItemTreeDomain one = labInspectItemTreeRepository.findOne(itemParentId);
                        one.setChildCount(one.getChildCount() == 0 ? 0 : (one.getChildCount() - 1));
                        LabInspectItemTreeDomain saveOne = labInspectItemTreeRepository.save(one);
                        if (saveOne == null) {
                            return new ResDto(Const.SERVER_ERROR, "删除二级时修改一级子类数量失败");
                        }
                    }
                } else {
                    return new ResDto(Const.SERVER_ERROR, "有子分类不能删除");
                }
            }
            return new ResDto(Const.SUCCESS, "删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            return new ResDto(Const.SERVER_ERROR, "删除失败");
        }

    }


    @Override
    public ResDto getLabInspectItemFrontPage(FrontPage frontPage) {
        int pageNum = frontPage.getPage();
        int pageSize = frontPage.getSize();
        Map<String, Object> conditionMap = frontPage.getCondition();
        LabInspectItemTreeQuery labInspectItemTreeQuery;
        if (null == conditionMap || conditionMap.isEmpty()) {
            //查询所有
            labInspectItemTreeQuery = new LabInspectItemTreeQuery();
        } else {
            String conditionMapJson = JsonMapper.defaultMapper().toJson(conditionMap);
            labInspectItemTreeQuery = JsonMapper.defaultMapper().fromJson(conditionMapJson, LabInspectItemTreeQuery.class);
        }
        Pageable pageRequest = new PageRequest(pageNum - 1, pageSize, new Sort(Sort.Direction.DESC, "gmt_created"));
        Page<LabInspectItemTreeDomain> mongoManagerPage = mongoManager.findPage(labInspectItemTreeQuery, pageRequest, LabInspectItemTreeDomain.class);
        ResDto resDto = new ResDto(Const.SUCCESS, "成功");
        ResDtoUtil.defaultUtil().pageDomainDtoToFrontDto(resDto, mongoManagerPage, LabInspectItemTreeDto.class, frontPage);
        return resDto;
    }

    @Override
    public ResDto getLabInspectItemList(LabInspectItemTreeQuery labInspectItemTreeQuery) {
        List<LabInspectItemTreeDomain> labInspectItemDomains = mongoManager.find(labInspectItemTreeQuery, LabInspectItemTreeDomain.class);
        List<LabInspectItemTreeDto> labInspectItemDtos = BeanMapper.mapList(labInspectItemDomains, LabInspectItemTreeDto.class);
        String labInspectItemDtosStr = JsonMapper.defaultMapper().toJson(labInspectItemDtos);
        ResDto resDto = new ResDto(ConstEum.SUCCESS);
        resDto.setDatas(labInspectItemDtosStr);
        return resDto;
    }

    /**
     * 查出所有的一级和二级和三级(带树结构)
     *
     * @return
     */
    @Override
    public ResDto getAllLabInspectItemList(List<String> itemSubcategoryList) {
        LabInspectItemTreeConditionQuery treeQuery = new LabInspectItemTreeConditionQuery();
        treeQuery.setStatus("0");
        if (itemSubcategoryList.size() > 0) {
            treeQuery.setItemSubcategoryList(itemSubcategoryList);
        }
        List<LabInspectItemTreeDomain> allDataList = mongoManager.find(treeQuery, LabInspectItemTreeDomain.class, new Sort(Sort.Direction.DESC, "item_order"));
        List<InspectItemHiddenDangerDto> treeByInspectItem = null;
        if (null != allDataList && allDataList.size() > 0) {
            treeByInspectItem = this.createTreeByInspectItem_All(allDataList);
        }
        String labInspectItemDtosStr = JsonMapper.defaultMapper().toJson(treeByInspectItem);
        ResDto resDto = new ResDto(ConstEum.SUCCESS);
        resDto.setDatas(labInspectItemDtosStr);
        resDto.setMsg("成功");
        return resDto;
    }

    /**
     * 获取所有的危险源隐患库列表
     *
     * @return
     */
    @Override
    public ResDto getAllLabDangerList() {
        try {
            LabInspectItemTreeQuery labInspectItemTreeQuery = new LabInspectItemTreeQuery();
            //先查询全部危险源隐患列表,再取一级，再取二级...(好处是只查询一次库)
            labInspectItemTreeQuery.setItemSubcategory("2");
            labInspectItemTreeQuery.setStatus("0");

            List<LabInspectItemTreeDomain> labInspectItemDomains = mongoManager.find(labInspectItemTreeQuery, LabInspectItemTreeDomain.class, new Sort(Sort.Direction.DESC, "item_order"));
            List<InspectItemHiddenDangerDto> treeByInspectItem = null;
            if (null != labInspectItemDomains && labInspectItemDomains.size() > 0) {
                treeByInspectItem = this.createTreeByInspectItem(labInspectItemDomains);
            }
            //List<LabInspectItemTreeDto> labInspectItemDtos = BeanMapper.mapList(labInspectItemDomains, LabInspectItemTreeDto.class);
            String labInspectItemDtosStr = JsonMapper.defaultMapper().toJson(treeByInspectItem);
            ResDto resDto = new ResDto(ConstEum.SUCCESS);
            resDto.setDatas(labInspectItemDtosStr);
            return resDto;
        } catch (Exception e) {
            e.printStackTrace();
            return new ResDto(Const.SERVER_ERROR, "获取所有的危险源隐患库失败");
        }

    }


    public List<InspectItemHiddenDangerDto> createTreeByInspectItem(List<LabInspectItemTreeDomain> domainList) {
        List<InspectItemHiddenDangerDto> dtoList = new ArrayList<>();
        for (LabInspectItemTreeDomain domain : domainList) {
            if (domain.getItemLevel().equals("1")) {
                InspectItemHiddenDangerDto dto = new InspectItemHiddenDangerDto();
                dto.setId(domain.getId());
                dto.setItemName(domain.getItemName());
                dto.setChildCount(domain.getChildCount());
                dto.setItemCategory(domain.getItemCategory());
                dto.setItemSubcategory(domain.getItemSubcategory());
                dto.setStatus(domain.getStatus());
                dto.setItemParentId(domain.getItemParentId());
                dto.setItemLevel(domain.getItemLevel());
                dtoList.add(dto);
                //只查出二级
                createTree(dto, domainList);
            }
        }
        return dtoList;
    }

    /**
     * 查出一级二级和三级
     *
     * @param domainList
     * @return
     */
    public List<InspectItemHiddenDangerDto> createTreeByInspectItem_All(List<LabInspectItemTreeDomain> domainList) {
        List<InspectItemHiddenDangerDto> dtoList = new ArrayList<>();
        for (LabInspectItemTreeDomain domain : domainList) {
            if (domain.getItemLevel().equals("1")) {
                InspectItemHiddenDangerDto dto = new InspectItemHiddenDangerDto();
                dto.setId(domain.getId());
                dto.setItemName(domain.getItemName());
                dto.setChildCount(domain.getChildCount());
                dto.setItemCategory(domain.getItemCategory());
                dto.setItemSubcategory(domain.getItemSubcategory());
                dto.setStatus(domain.getStatus());
                dto.setItemParentId(domain.getItemParentId());
                dto.setItemLevel(domain.getItemLevel());
                dto.setItemOrder(domain.getItemOrder() == null ? null : domain.getItemOrder().toString());
                dtoList.add(dto);

                createTreeBy(dto, domainList);
            }
        }
        return dtoList;
    }

    /**
     * 查出来的是一级二级 无三级
     * 参见ResourceServiceImpl$createTree
     *
     * @param inspectItemHiddendto
     * @param domainList           return void
     * @方法名称: createTree
     * @功能描述: 递归创建菜单树
     * @作者:杨云博
     * @创建时间:2017/12/26 14:46
     */
    private void createTree(InspectItemHiddenDangerDto inspectItemHiddendto, List<LabInspectItemTreeDomain> domainList) {
        for (LabInspectItemTreeDomain domain : domainList) {
            //这里只选择二级
            if (domain.getItemLevel() != null && domain.getItemLevel().equals("2") && inspectItemHiddendto.getId().equals(domain.getItemParentId())) {
                List<InspectItemHiddenDangerDto> childrenList = inspectItemHiddendto.getChildDtoList();
                if (childrenList == null) {
                    childrenList = new ArrayList<>();
                }

                InspectItemHiddenDangerDto dto2 = new InspectItemHiddenDangerDto();
                dto2.setId(domain.getId());
                dto2.setItemName(domain.getItemName());
                dto2.setChildCount(domain.getChildCount());
                dto2.setItemCategory(domain.getItemCategory());
                dto2.setItemSubcategory(domain.getItemSubcategory());
                dto2.setStatus(domain.getStatus());
                dto2.setItemParentId(domain.getItemParentId());
                dto2.setItemLevel(domain.getItemLevel());

                childrenList.add(dto2);
                inspectItemHiddendto.setChildDtoList(childrenList);
            }
        }
    }

    @Override
    public ResDto deleteLabInspectItemById(LabInspectItemTreeDto labInspectItemTreeDto) {
        return null;
    }


    //***************************************报表统计***************************************
    /*
     * 危险源分布统计
     * */
    @Override
    public ResDto getDangerStatisticsList() {

//        Criteria critera = Criteria.where("inspectItem.item_category").is("0").and("inspectItem.item_level").is("1");
//        String fields[] = {"$unit_id","$inspectItem_id"};
//        Aggregation aggregation = Aggregation.newAggregation(
//                Aggregation.lookup("tb_lab","lab_id","_id","lab"),
//                Aggregation.lookup("tb_lab_inspect_item_tree","inspectItem_id","_id","inspectItem"),
//                Aggregation.unwind("$lab"),
//                Aggregation.unwind("$inspectItem"),
//
//
//                Aggregation.match(critera),
//
//
//                Aggregation.group(fields).sum("lab_id").as("count")
//
////                Aggregation.project()
//
//
//        );
//
//        mongoTemplate.aggregate(aggregation,"tb_lab_inspect_item_relation",);

        /* 创建Lab的lookup操作 */
        Map<String, String> labMap = new HashMap<>();
        labMap.put("from", "tb_lab");
        labMap.put("localField", "lab_id");
        labMap.put("foreignField", "_id");
        labMap.put("as", "lab");
        DBObject labLookUp = new BasicDBObject("$lookup", labMap);

        /* 创建Lab的lookup操作 */
        Map<String, String> inspectItemMap = new HashMap<>();
        inspectItemMap.put("from", "tb_lab_inspect_item_tree");
        inspectItemMap.put("localField", "inspectItem_id");
        inspectItemMap.put("foreignField", "_id");
        inspectItemMap.put("as", "inspectItem");
        DBObject inspectItemLookUp = new BasicDBObject("$lookup", inspectItemMap);

        /* 创建unwind操作 */
        DBObject unwind1 = new BasicDBObject("$unwind", "$lab");
        DBObject unwind2 = new BasicDBObject("$unwind", "$inspectItem");

        /* 创建match操作 */
        BasicDBObject[] matchArray = {
                new BasicDBObject("inspectItem.item_category", new BasicDBObject("$eq", "0")),
                new BasicDBObject("inspectItem.item_level", new BasicDBObject("$eq", "1")),
                new BasicDBObject("lab.status", new BasicDBObject("$eq", "0"))
        };
        DBObject match = new BasicDBObject("$match", new BasicDBObject("$and", matchArray));

        /* 创建group1操作 */
        Map<String, String> groupIdMap = new HashMap<>();
        groupIdMap.put("unit_id", "$lab.unit_id");
        groupIdMap.put("unit_name", "$lab.unit_name");
        groupIdMap.put("inspectItem_id", "$inspectItem_id");
        groupIdMap.put("inspectItem_name", "$inspectItem.item_name");

        Map<String, Object> group1Map = new HashMap<>();
        group1Map.put("_id", groupIdMap);
        group1Map.put("count", new BasicDBObject("$sum", 1));
        DBObject group1 = new BasicDBObject("$group", group1Map);

        /* 创建project1操作 */
        Map<String, Object> project1Map = new HashMap<>();
        project1Map.put("unit_id", "$_id.unit_id");
        project1Map.put("unit_name", "$_id.unit_name");
        project1Map.put("inspectItem_id", "$_id.inspectItem_id");
        project1Map.put("inspectItem_name", "$_id.inspectItem_name");
        project1Map.put("count", 1);
        project1Map.put("_id", 0);
        DBObject project1 = new BasicDBObject("$project", project1Map);

        /* 创建group2操作 */
        Map<String, String> groupId2Map = new HashMap<String, String>() {
            {
                put("unit_id", "$unit_id");
                put("unit_name", "$unit_name");
            }
        };
        Map<String, String> resultMap = new HashMap<String, String>() {
            {
                put("inspectItem_id", "$inspectItem_id");
                put("inspectItem_name", "$inspectItem_name");
                put("count", "$count");
            }
        };
        DBObject groupResult = new BasicDBObject("$push", resultMap);
        Map<String, Object> resultMap2 = new HashMap<String, Object>() {
            {
                put("_id", groupId2Map);
                put("result", groupResult);
            }
        };
        DBObject group2 = new BasicDBObject("$group", resultMap2);

        /* 创建project2操作 */
        Map<String, Object> project2Map = new HashMap<>();
        project2Map.put("unit_id", "$_id.unit_id");
        project2Map.put("unit_name", "$_id.unit_name");
        project2Map.put("result", "$result");
        project2Map.put("_id", 0);
        DBObject project2 = new BasicDBObject("$project", project2Map);


        DBCollection dbCollection = mongoTemplate.getCollection("tb_lab_inspect_item_relation");
        List<DBObject> list = new ArrayList<>();
        list.add(labLookUp);
        list.add(inspectItemLookUp);
        list.add(unwind1);
        list.add(unwind2);
        list.add(match);
        list.add(group1);
        list.add(project1);
        list.add(group2);
        list.add(project2);
        AggregationOutput aggregate = dbCollection.aggregate(list);
        Iterable<DBObject> results = aggregate.results();

        //获取检查项列表
        LabInspectItemTreeQuery labInspectItemTreeQuery = new LabInspectItemTreeQuery();
        labInspectItemTreeQuery.setItemLevel("1");
        labInspectItemTreeQuery.setStatus("0");
        labInspectItemTreeQuery.setItemCategory("0");
        List<LabInspectItemTreeDomain> labInspectItemDomains = mongoManager.find(labInspectItemTreeQuery, LabInspectItemTreeDomain.class);
        List<LabInspectItemTreeDto> labInspectItemDtos = BeanMapper.mapList(labInspectItemDomains, LabInspectItemTreeDto.class);

        Map<String, Object> resultHashMap = new HashMap<>();
        resultHashMap.put("results", (ArrayList) results);
        resultHashMap.put("check_item", labInspectItemDtos);
        String resultHashMapStr = JsonMapper.defaultMapper().toJson(resultHashMap);
        return new ResDto(Const.SUCCESS, "成功", resultHashMapStr);
    }


    /*
     * 按院系统计危险源分布实验室数量
     * */
    @Override
    public ResDto getDangerStatisticsListByUnitId(String unitId) {

        /* 创建Lab的lookup操作 */
        Map<String, String> labMap = new HashMap<>();
        labMap.put("from", "tb_lab");
        labMap.put("localField", "lab_id");
        labMap.put("foreignField", "_id");
        labMap.put("as", "lab");
        DBObject labLookUp = new BasicDBObject("$lookup", labMap);

        /* 创建Lab的lookup操作 */
        Map<String, String> inspectItemMap = new HashMap<>();
        inspectItemMap.put("from", "tb_lab_inspect_item_tree");
        inspectItemMap.put("localField", "inspectItem_id");
        inspectItemMap.put("foreignField", "_id");
        inspectItemMap.put("as", "inspectItem");
        DBObject inspectItemLookUp = new BasicDBObject("$lookup", inspectItemMap);

        /* 创建unwind操作 */
        DBObject unwind1 = new BasicDBObject("$unwind", "$lab");
        DBObject unwind2 = new BasicDBObject("$unwind", "$inspectItem");

        /* 创建match操作 */
        BasicDBObject[] matchArray;
        if (unitId.equals("--SUM--SUM--SUM--SUM--SUM--SUM--")) {
            BasicDBObject[] matchArray1 = {
                    new BasicDBObject("inspectItem.item_category", new BasicDBObject("$eq", "0")),
                    new BasicDBObject("inspectItem.item_level", new BasicDBObject("$eq", "1"))
            };
            matchArray = matchArray1;
        } else {
            BasicDBObject[] matchArray2 = {
                    new BasicDBObject("lab.unit_id", new BasicDBObject("$eq", unitId)),
                    new BasicDBObject("inspectItem.item_category", new BasicDBObject("$eq", "0")),
                    new BasicDBObject("inspectItem.item_level", new BasicDBObject("$eq", "1"))
            };
            matchArray = matchArray2;
        }
        DBObject match = new BasicDBObject("$match", new BasicDBObject("$and", matchArray));

        /* 创建group1操作 */
        Map<String, String> groupIdMap = new HashMap<>();
        groupIdMap.put("unit_id", "$lab.unit_id");
        if (!unitId.equals("--SUM--SUM--SUM--SUM--SUM--SUM--")) {
            groupIdMap.put("unit_name", "$lab.unit_name");
        }

        groupIdMap.put("inspectItem_id", "$inspectItem_id");
        groupIdMap.put("inspectItem_name", "$inspectItem.item_name");

        Map<String, Object> group1Map = new HashMap<>();
        group1Map.put("_id", groupIdMap);
        group1Map.put("count", new BasicDBObject("$sum", 1));
        DBObject group1 = new BasicDBObject("$group", group1Map);

        /* 创建project1操作 */
        Map<String, Object> project1Map = new HashMap<>();
        if (!unitId.equals("--SUM--SUM--SUM--SUM--SUM--SUM--")) {
            project1Map.put("unit_id", "$_id.unit_id");
            project1Map.put("unit_name", "$_id.unit_name");
        }

        project1Map.put("inspectItem_id", "$_id.inspectItem_id");
        project1Map.put("inspectItem_name", "$_id.inspectItem_name");
        project1Map.put("count", 1);
        project1Map.put("_id", 0);
        DBObject project1 = new BasicDBObject("$project", project1Map);

        /* 创建group2操作 */
        Map<String, String> groupId2Map = new HashMap<String, String>() {
            {
                put("unit_id", "$unit_id");
                put("unit_name", "$unit_name");
            }
        };
        Map<String, String> resultMap = new HashMap<String, String>() {
            {
                put("inspectItem_id", "$inspectItem_id");
                put("inspectItem_name", "$inspectItem_name");
                put("count", "$count");
            }
        };
        DBObject groupResult = new BasicDBObject("$push", resultMap);
        Map<String, Object> resultMap2 = new HashMap<String, Object>() {
            {
                put("_id", groupId2Map);
                put("result", groupResult);
            }
        };
        DBObject group2 = new BasicDBObject("$group", resultMap2);

        /* 创建project2操作 */
        Map<String, Object> project2Map = new HashMap<>();
        project2Map.put("unit_name", "$_id.unit_name");
        project2Map.put("result", "$result");
        project2Map.put("_id", 0);
        DBObject project2 = new BasicDBObject("$project", project2Map);


        DBCollection dbCollection = mongoTemplate.getCollection("tb_lab_inspect_item_relation");
        List<DBObject> list = new ArrayList<>();
        list.add(labLookUp);
        list.add(inspectItemLookUp);
        list.add(unwind1);
        list.add(unwind2);
        list.add(match);
        list.add(group1);
        list.add(project1);
        list.add(group2);
        list.add(project2);
        AggregationOutput aggregate = dbCollection.aggregate(list);
        Iterable<DBObject> results = aggregate.results();
        return new ResDto(Const.SUCCESS, "成功", results.toString());
    }
}
